﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Mvc;
using Microsoft.IdentityModel.Claims;
using AzureGames.Data;
using System.Threading;
using Microsoft.IdentityModel.Protocols.WSFederation;
using AzureGames.Domain;
using AzureGames.Domain.Services;
using System.Web.Security;
using Microsoft.IdentityModel.Web;
using System.Text;
using System.Configuration;

namespace AzureGames.Web.Controllers
{
    public class AccountController : Controller
    {
        //
        // GET: /Account/
        private readonly IUserRepository userRepository;
        private readonly string IdentityProviderClaimType = "http://schemas.microsoft.com/accesscontrolservice/2010/07/claims/identityprovider";

        public AccountController(IUserRepository userRepository)
        {
            this.userRepository = userRepository;
        }

        public ActionResult LogOn(string returnUrl)
        {
            ViewBag.Realm = ConfigurationManager.AppSettings["ACSRealm"];            
            
            return View();
        }

      
       
        public ActionResult LogOut()
        {
            WSFederationAuthenticationModule fam = new WSFederationAuthenticationModule();
            try
            {
                FormsAuthentication.SignOut();
            }
            finally
            {
                fam.SignOut(true); //not sure if this should be true or not
            }
            return Redirect("~/");
        }

        [HttpPost]
        public ActionResult LogOn()
        {
            if (this.Request.IsAuthenticated)
            {
                // Ensure user profile
                var nameIdentifier = this.GetClaimValue(ClaimTypes.NameIdentifier);

                var user = this.userRepository.LoginUser(nameIdentifier);
                
                // new user
                if (user == null)
                {
                    var loginType = this.GetClaimValue(IdentityProviderClaimType);
                    user = new Model.User(Guid.NewGuid().ToString(), Resources.Account_DefaultUserName)
                    {
                        NameIdentifier = nameIdentifier,                        
                        FirstName = Resources.Account_DefaultUserFirstName,
                        LastName = Resources.Account_DefaultUserLastName,
                        LoginType = loginType,
                        Name = Resources.Account_DefaultUserName,
                        AvatarImage = new Guid(Resources.Account_DefaultAvaterImage)                        
                    };

                   
                    this.userRepository.AddUser(user);
                    Session["User"] = user;

                    return RedirectToAction("Profile", "User");
                }
               
                Session["User"] = user;                
             }

            return Redirect("~/");
        }


        
        //public ActionResult L1()
        //{

        //    var nameIdentifier = "XKRfKaACuPfmy11bcHq2QlCAcglHi5JbrjhtVl8R/Xs=";
        //    FormsAuthentication.SetAuthCookie(nameIdentifier, false);

        //    var user = this.userRepository.LoginUser(nameIdentifier);

                
        //        Session["User"] = user;
        //    return Redirect("~/");
        //}

        
        //public ActionResult L2()
        //{

        //    var nameIdentifier = "fdfd";
        //    FormsAuthentication.SetAuthCookie(nameIdentifier, false);

        //    var user = this.userRepository.LoginUser(nameIdentifier);


        //    Session["User"] = user;
        //    return Redirect("~/");
        //}

        
        //public ActionResult L3()
        //{

        //    var nameIdentifier = "xdxdfdfd";
        //    FormsAuthentication.SetAuthCookie(nameIdentifier, false);

        //    var user = this.userRepository.LoginUser(nameIdentifier);


        //    Session["User"] = user;
        //    return Redirect("~/");
        //}


        [Authorize]
        public ActionResult Profile()
        {
            Model.User user = Session["User"] as Model.User;
            return View(user);
        }

        [HttpPost]
        public ActionResult Profile(Model.User user)
        {
            if (ModelState.IsValid)
            {
                //TODO if user exists, update, otherwise add
                this.userRepository.AddUser(user);
            }
            return Redirect("~/");
        }

        public JavaScriptResult ACSString()
        {
            string baseString = "https://socialgames.accesscontrol.windows.net:443/v2/metadata/IdentityProviders.js?protocol=wsfederation&amp;realm={0};reply_to=&amp;context=&amp;request_id=&amp;version=1.0&amp;callback=ShowSigninPage";
            //localhost
            //<script src="https://socialgames.accesscontrol.windows.net:443/v2/metadata/IdentityProviders.js?protocol=wsfederation&amp;realm=http%3a%2f%2flocalhost%3a81%2f&amp;reply_to=&amp;context=&amp;request_id=&amp;version=1.0&amp;callback=ShowSigninPage" type="text/javascript"></script>
            //staging
            //<script src="https://socialgames.accesscontrol.windows.net:443/v2/metadata/IdentityProviders.js?protocol=wsfederation&amp;realm=http%3a%2f%2f9af11904ee0d4e1998dafb97d407b287.cloudapp.net%2f&amp;reply_to=&amp;context=&amp;request_id=&amp;version=1.0&amp;callback=ShowSigninPage" type="text/javascript"></script>
            var realmString = GetRealm(HttpContext.Request);
            //http%3a%2f%2flocalhost%3a81%2f&amp
            var encoded = HttpUtility.UrlEncode(realmString);
            var result = string.Format(baseString, realmString);

            return JavaScript(result);
        }
         

        private string GetClaimValue(string claimType)
        {
            if (!Thread.CurrentPrincipal.Identity.IsAuthenticated)
            {
                throw new InvalidOperationException("User is not authenticated");
            }

            var claimsIdentity = (IClaimsIdentity)Thread.CurrentPrincipal.Identity;

            if (!claimsIdentity.Claims.Any(c => c.ClaimType.Equals(claimType, StringComparison.OrdinalIgnoreCase)))
            {
                throw new InvalidOperationException("Claim not found: " + claimType);
            }

            return claimsIdentity.Claims.FirstOrDefault(c => c.ClaimType.Equals(claimType, StringComparison.OrdinalIgnoreCase)).Value;
        }

        private string GetRealm(HttpRequestBase request)
        {
            
            var realm = new StringBuilder();

            realm.Append(request.Url.Scheme);
            realm.Append("://");
            realm.Append(request.Headers["Host"] ?? request.Url.Authority);
            realm.Append(request.ApplicationPath);

            if (!request.ApplicationPath.EndsWith("/", StringComparison.OrdinalIgnoreCase))
            {
                realm.Append("/");
            }

            return realm.ToString();
        }
    }
}
